<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Search</title>
    <style>
        .on-over {
            background-color: rgba(0, 0, 0, 0.2);
            cursor: pointer;
        }
        .board {
            width: 200px; 
            height: 200px; 
            background-color:rgba(255, 255, 255, 0.7); 
            line-height: 1.2em; 
            border: 2px solid; 
            border-color: gray;     
            opacity: 0.0;       
        }
    </style>
</head>
<body style="background-color: blanchedalmond;">
    <div>
        <div class="search-list"></div>
        <input type="text" oninput="AppImpl.onInput.call(this);" onfocus="document.querySelector('.board').style.opacity=1.0;" onblur="document.querySelector('.board').style.opacity=0.0;">
        <div class="board">
        </div>
        <script>
            
            // This is a list for searchable in the input dialog.
            let words = [
                "안녕하세요", "사과", "바나나", 
                "사과나무", "사과쥬스", "사과농장", 
                "사과하세요","오이쥬스", "오렌지", "초콜릿",
                "blue", "green", "practice","program","dream","grass"
            ];          

            const RSEvent = {

                over() {
                    this.className = 'on-over';
                },
                
                out() {
                    this.className = '';
                },
                
                setText() {
                    document.querySelector("input").value = this.firstChild.textContent;
                }
            }
                        
            let rs = {
                deltaTime: performance.now()
            };        
              
            class AppImpl {

                constructor() {
                    this.initWithScreen();
                }

                initWithScreen() {
                    const listElem = document.querySelector(".search-list");
                    const spanElem = document.createElement("span");
                    spanElem.textContent = "검색 가능한 목록 : ";   
                    listElem.appendChild(spanElem);
                    
                    words.forEach(i => {
                        const divElem = document.createElement("div");
                        const spanElem = document.createElement("span");
                        
                        spanElem.textContent = JSON.stringify(i);                
                        divElem.appendChild(spanElem);
                        listElem.appendChild(divElem);
                    }); 
                }
   
                removeBoard() {
                    const board = document.querySelector(".board");
                    for(let elem of board.children) {
                        board.removeChild(elem);
                    }
                }
                
                addBoard(word) {
                    const board = document.querySelector(".board");
                    
                    let divElem = document.createElement("div");
                    let spanElem = document.createElement("span");
                    spanElem.textContent = word;
                    
                    divElem.appendChild(spanElem);
                    divElem.onmouseout = RSEvent.out;
                    divElem.onmouseover = RSEvent.over;
                    divElem.onmousedown = RSEvent.setText;
                    
                    board.appendChild(divElem);
                }

                static async onInput() {
                    // 데이터 찾기
                    console.clear();
                    if(!App) return;
                    App.removeBoard();
                    const query = document.querySelector('input').value;
                    if(query.length < 2) {
                        return;
                    }
                    if(performance.now() - rs.deltaTime < 1800) {
                        rs.deltaTime = performance.now();
                        return;
                    }
                    var promise = Database.searchQuery(query, 6);
                    await promise.then(value => {
                        App.removeBoard();
                        value.forEach(i => {
                            App.addBoard(i);
                        })
                    }).catch(err => {
                        console.warn("Error!");
                    });         
                }                
            }
                        
            class Database {
                
                static open() {
                    this._db = openDatabase("Dictionary", "1.0", "test", 2 * 1024 * 1024);
                }
                
                static create() {
                    if(!this._db) return;
                    const db = this._db;
                    db.transaction(function(tx) {
                        tx.executeSql("CREATE TABLE IF NOT EXISTS Dictionary (name varchar(30))");
                    });                                
                }
                
                static remove() {
                    if(!this._db) return;
                    const db = this._db;     
                    db.transaction(function (tx) {
                        tx.executeSql('DROP TABLE Dictionary');
                    });
                }
                
                static addItems(words) {
                    if(!this._db) return;
                    if(!words) return;
                    const db = this._db;
                    words.forEach(i => {
                        // 데이터 추가
                        db.transaction(function(tx) {
                            tx.executeSql("INSERT INTO Dictionary(name) VALUES(?)", [i], (tx, result) => {
     
                            }, (err) => {

                            })
                        });                    
                    });                    
                }
                    
                static removeData(words) {
                    if(!this._db) return;
                    if(!words) return;
                    const db = this._db;
                    words.forEach(word => {
                        db.transaction(function(tx) {
                            tx.executeSql(`DELETE FROM Dictionary WHERE name='${word}'`, [], (tx, result) => {
                                
                            }, (err) => {

                            });
                        });                    
                    });                      
                }

                static removeAllData() {
                    if(!this._db) return;
                    if(!words) return;
                    const db = this._db;
                    words.forEach(word => {
                        db.transaction(function(tx) {
                            tx.executeSql(`DELETE FROM Dictionary`, [], (tx, result) => {
                                
                            }, (err) => {

                            });
                        });                    
                    });                      
                }                    
                
                static searchQuery(query, count) {
                    if(!this._db) return;
                    const db = this._db;                    
                    return new Promise((resolve, reject) => {
                        db.transaction(function(tx) {
                            tx.executeSql(`SELECT name FROM Dictionary WHERE name LIKE '%${query}%' limit ${count}`, [], function(table, result) {
                                let data = [];
                                for(var i of result.rows) { 
                                    data.push(i["name"]);
                                }
                                resolve(data);
                            }, reject);
                        });    
                    });
                }                
            }

            // 앱 생성
            const App = new AppImpl();                
                            
            // DB 생성
            Database.open();
            
            // 테이블 삭제
            Database.remove();
            
            // 테이블 생성
            Database.create();
            
            // 데이터 추가
            Database.addItems(words);
                
            </script>        
        </div>
        
    </body>
    </html>